import { Injectable, Logger } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { IResponse } from 'src/interfaces/response.interface';
import { TrimProduct } from 'src/interfaces/trim-product.interface';
import { Product, ProductDocument } from 'src/schemas/product.schema';
import { Record, RecordDocument } from 'src/schemas/record.schema';
import { to } from 'src/utils/to';
import { UpdateProductDto } from './dto/update-product.dto';
import * as categories from '../../assets/json/category.json';
import { debug } from 'console';
import { RecordType } from 'src/utils/record-type.enum';

const logger = new Logger('product.service');
@Injectable()
export class ProductService {
  private response: IResponse;
  constructor(
    @InjectModel('Product') private productModel: Model<ProductDocument>,
    @InjectModel('Record') private recordModel: Model<RecordDocument>,
  ) {}

  /**
   * @description 商品入库，增加至数据库
   * @date 2021-10-06
   * @param createProductDto
   * @returns {*}
   */
  async create(createProductDto: Product) {
    let trimProduct: TrimProduct = this.trimProductObj(createProductDto);
    let [err, dbData] = await to(this.productModel.findOne(trimProduct));
    try {
      if (err) {
        this.response = {
          code: 1,
          msg: '产品查找失败',
        };
        throw this.response;
      } else if (dbData) {
        // 如果之前添加过
        let product: Product = dbData;
        product.count += createProductDto.count;
        product.imei = product.imei.concat(createProductDto.imei);
        let [err, res] = await to(
          this.productModel.findOneAndUpdate(trimProduct, product),
        );
        if (res) {
          this.response = { code: 0, msg: '入库成功' };
        } else if (err) {
          throw Error(err);
        }
      } else {
        // 如果之前没有添加过
        const createProduct = new this.productModel(createProductDto);
        createProduct.save();
        this.response = { code: 0, msg: '入库成功' };
      }
    } catch (error) {
      return error;
    }
    return this.response;
  }

  /**
   * @description 获取所有的手机数据 (库存)
   * @date 2021-10-06
   * @returns {*}
   */
  async findAll() {
    const [err, data] = await to(this.productModel.find());
    try {
      if (err) {
        this.response = {
          code: 1,
          msg: '查找全部数据失败',
        };
        throw this.response;
      } else {
        return data;
      }
    } catch (error) {
      return this.response;
    }
  }

  async findOne(id: string) {
    let [err, data] = await to(this.productModel.findById(id));
    try {
      if (err) {
        this.response = { code: 1, msg: `查找失败 ${err}` };
        throw this.response;
      } else if (data) {
        return data;
      }
    } catch (error) {
      return error;
    }
  }

  async findCategory() {
    logger.debug(categories);
    return categories;
  }

  /**
   * @description 商品出库更新IMEI列表
   * @date 2021-10-07
   * @param id
   * @param updateProductDto
   * @returns {*}
   */
  async update(id: string, record: Record) {
    try {
      record.type = RecordType.Sell;
      await this.removeIMEI(id, record.product);
      await this.recordModel.create(record);
    } catch (error) {
      return error;
    } finally {
      return this.response;
    }
  }

  /**
   * @description 根据ID删除
   * @date 2021-10-07
   * @param id
   * @returns {*}
   */
  async remove(id: string) {
    let [err, data] = await to(this.productModel.findByIdAndDelete(id));
    if (data) {
      this.response = {
        code: 0,
        msg: '删除成功',
      };
      return this.response;
    } else if (err) {
      console.log(err);
    }
  }

  /**
   * @description 删除指定IMEI
   * @param id
   * @param updateProductDto
   * @returns {*}
   */
  async removeIMEI(id: string, updateProductDto: UpdateProductDto) {
    try {
      let dbProduct: Product = await this.findOne(id);
      dbProduct = this.removeIMEIFromProduct(
        dbProduct,
        updateProductDto.checkIMEI,
      );
      if (dbProduct.count === 0) this.remove(id);
      else {
        this.productModel.findByIdAndUpdate(id, dbProduct);
      }
      let [err, data] = await to(
        this.productModel.findByIdAndUpdate(id, dbProduct),
      );
      if (err) {
        this.response = {
          code: 1,
          msg: `删除失败 ${err}`,
        };
        throw this.response;
      }
      return dbProduct;
    } catch (error) {
      return error;
    }
  }

  private trimProductObj(product: Product): TrimProduct {
    let trimProduct: TrimProduct = {
      brand: product.brand,
      color: product.color,
      model: product.model,
      ram: product.ram,
      storage: product.storage,
    };
    return trimProduct;
  }

  /**
   * @description 从Product对象里去除IMEI
   * @date 2021-10-12
   * @private
   * @param product
   * @param checkIMEI
   * @returns {*}
   */
  private removeIMEIFromProduct(product: Product, checkIMEI: string): Product {
    for (let i = 0; i < product.imei.length; i++) {
      if (product.imei[i] === checkIMEI) {
        logger.log(i);

        product.imei.splice(i, 1);
        break;
      }
    }
    product.count--;
    return product;
  }
}
